<template>
  <div id="create-page" class="max-w-md w-full my-0 mx-a pt-4 pb-20">
    <div id="easy-model-container" class="px-4">
      <ThinFatTitle thin-text="Easy" fat-text="Model" />
      <ModelList
        plus
        closable
        :list="modelList"
        :on-tap-card="onTapCard"
        :on-delete="handleDelete"
      />
    </div>

    <div id="custom-prompt-container" class="mt-6 w-full px-4">
      <ThinFatTitle thin-text="Custom " fat-text="Prompt" />
      <PromptInput :default-value="feed?.customPrompt" v-model="prompt" />
    </div>

    <div id="canvas-ratio-container" class="mt-6 w-full px-4">
      <ThinFatTitle thin-text="Canvas" fat-text="Ratio" />
      <RatioList v-model="curRatioIndex" />
    </div>

    <div id="advance-container" class="mt-10 w-full px-4">
      <ThinFatTitle thin-text="Advance" @click="handleAdvance">
        <template #fatNode>
          <n-icon
            id="arrow-icon"
            :size="30"
            class="mb--0.6 arrow-icon"
            :style="{ transform: `rotate(${showAdvance ? 0.25 : 0}turn)` }"
          >
            <ChevronRightSharp />
          </n-icon>
        </template>
      </ThinFatTitle>
      <template v-if="showAdvance">
        <ThinFatTitle thin-text="Negative" fat-text="Prompt" />
        <PromptInput
          :rows="2"
          :default-value="feed?.negativePrompt"
          placeholder="Input anything you do not want..."
          v-model="negativePrompt"
        />
      </template>
    </div>

    <div class="fixed bottom-4 w-full max-w-md px-4"><CreateBtn @click="handleCreate" /></div>
    <ModelPool
      :open="modelPoolOpen"
      :on-close="onClose"
      v-model="curCategory"
      :height="poolHeight()"
    />
  </div>
</template>

<script setup lang="ts">
import type { DrawParams, Model } from '@/service/types'
import type { ItemOption } from '../home/waterfall/types'
import ThinFatTitle from './components/ThinFatTitle.vue'
import RatioList from './components/RatioList.vue'
import ModelList from '@/components/ModelList.vue'
import { ChevronRightSharp } from '@vicons/material'
import { NIcon } from 'naive-ui'
import PromptInput from './components/PromptInput.vue'
import CreateBtn from './components/CreateBtn.vue'
import ModelPool from './components/ModelPool.vue'
import type { CardType } from '@/typing'
import { getBrowserInterfaceSize } from '@/utils/helper'
import router from '@/router'
import Routes from '@/router/routes'
import useNavigator from '@/utils/hooks/useNavigator'
import { useModelCategory } from '@/stores/useModelCategory'
import { findRatioIndex, selectedModelsProvider, } from './useCreate'
import { ratioData } from '@/constant'

const { data: categories } = useModelCategory()
const { animateTo } = useNavigator()
defineOptions({ name: 'CreatePage' })
const feed = ref<ItemOption>()
/** 渲染参数: 正向咒语 */
const prompt = ref('')
/** 渲染参数: 反向咒语 */
const negativePrompt = ref('')
/** 比例索引 */
const curRatioIndex = ref<number>(0)
/** 渲染参数: 比例宽高 */
const ratioSize = computed(()=>{
  return ratioData[curRatioIndex.value]
})
const modelList = ref<Model[]>([])
/** 渲染参数: tags, 即模型编码集合 */
const modelsCode = computed(()=>{
  const result = modelList.value.map(ele=>ele.model_code!)
  return result.join(',')
})
const showAdvance = ref<boolean>(false)
/** 模型池打开状态 */
const modelPoolOpen = ref(false)
const curCategory = ref<string>()
const updateModelList = (models: Model[], categoryCode?: string) => {
  modelList.value = models
}
/**
 * @description 移动模型列表到指定编码的位置
 * @description 如果没有指定编码，则跳转到 plus-btn
 * @param categoryCode 分类编码
 */
const moveModelList = (categoryCode?: string) => {
  const targetId = categoryCode ? `model-card-${categoryCode}` : 'plus-btn'
  setTimeout(() => {
    animateTo(targetId, 'model-list')
  }, 100)
}
// 提供给子级的数据
provide(selectedModelsProvider, { selectedModels: modelList, updateModelList, moveModelList })
watch(
  [() => history.state.modelList, () => history.state.feed],
  ([newList, newFeed]) => {
    try {
      feed.value = JSON.parse(newFeed)
      modelList.value = JSON.parse(newList)
      if (!feed.value) return
      prompt.value = feed.value.customPrompt || ''
      curRatioIndex.value = findRatioIndex({ w: feed.value.width, h: feed.value.height })
    } catch (error) {
      console.error('create-page: feed and modelList parsed error', error)
    }
  },
  { immediate: true }
)
const poolHeight = () => {
  const container = document.getElementById('easy-model-container')
  if (!container) return 0
  const height = container.clientHeight + 25
  return getBrowserInterfaceSize().pageHeight - height
}
/** 点击模型 */
const onTapCard = (card: CardType, index?: number) => {
  // 如果是添加按钮
  if (card === 'plus') {
    let categoryCode = modelList.value[0].category_code
    // 对比 selectedModels
    // 从模型分类列表里找到第一个没有选择的分类
    for (const ele of categories) {
      const finded = modelList.value.find((item) => item.category_code === ele.category_code)
      if (!finded) {
        categoryCode = ele.category_code
        break
      }
    }
    curCategory.value = categoryCode
  } else {
    curCategory.value = card.category_code
  }
  modelPoolOpen.value = true
}
const handleDelete = (model: Model) => {
  const newList = modelList.value.filter((ele) => ele.model_code !== model.model_code)
  modelList.value = newList
}
const handleAdvance = () => {
  showAdvance.value = !showAdvance.value
}
const onClose = () => {
  modelPoolOpen.value = false
}
const handleCreate = () => {

  const spell_ext_args = {model_weight: {[modelList.value[0].category_code!]: 1}}
  const data:DrawParams = {
    prompt:prompt.value,
    negative_prompt:negativePrompt.value,
    tags: modelsCode.value,
    cropped_width: ratioSize.value.w,
    cropped_height: ratioSize.value.h,
    package_name: 'com.ai.polyverse.spell',
    version: '1.3.33+46',
    task_index: 1,
    task_type: 'Txt2img',
    mode: 'GENERAL',
    slow_pass: true,
    spell_ext_args: JSON.stringify(spell_ext_args)
  }
  router.push({ name: Routes.drawResult, state: {drawData: data} })
}
</script>

<style scoped>
.arrow-icon {
  transition: all 0.2s;
}
</style>
